<?php
namespace app\teacher\controller;

use app\teacher\controller\Base;

class Upload extends Base
{
    /**
     * 图片上传
     * @return [type] [description]
     */
    public function uploadImage()
    {
        // 获取表单上传文件 例如上传了001.jpg
        $file = request()->file('file');
        if (empty($file)) {
            return $this->fail('请上传文件');
        }
        $rootPath = './'; // 设置附件上传根目录
        $subName  = 'uploads';
        // 移动到框架应用根目录/uploads/ 目录下
        $info = $file->validate(['size' => 3145728, 'ext' => 'jpg,png,gif'])->move($rootPath . $subName);
        if ($info) {
            $file_info = $info->getInfo();
            $save_path = str_replace('\\', '/', $info->getSaveName());
            //添加到file表
            $info->md5();
            $path = ltrim($rootPath . $subName . '/' . $save_path, '.');
            $data = [
                'type_id'     => 1,
                'title'        => $file_info['name'],
                'md5'         => $info->md5(),
                'path'        => $path,
                'size'        => $file_info['size'],
                'create_time' => time(),
            ];
            $id = model('File')->add($data);
            if ($id) {
                return $this->ok(['id' => $id, 'path' => request()->domain() . $path]);
            } else {
                return $this->fail('服务器繁忙，上传失败');
            }
        } else {
            // 上传失败获取错误信息
            return $this->fail($file->getError());
        }
    }

    /**
     * 文件上传
     * @return [type] [description]
     */
    public function chunk()
    {
        // 唯一ID
        $guid = request()->param('guid');
        // 分片序号
        $chunk = request()->param('chunk', 1, 'intval');
        // 总分片数
        $chunks = request()->param('chunks', 1, 'intval');
        // 获取表单上传文件 例如上传了001.jpg
        $file    = request()->file('file');
        $tmp_dir = './uploads/tmp/' . $guid;
        // 分片保存临时名称
        $tmp_name = $this->getTmpName($chunks, $chunk);
        // 移动到框架应用根目录/uploads/ 目录下
        $info = $file->move($tmp_dir, $tmp_name);
        if ($info) {
            if ($chunk >= $chunks) {
                // 文件信息
                $file_info = $info->getInfo();
                // 删除对象，不然无法删除临时文件
                unset($info);
                $data = $this->mergeChunk($tmp_dir, $chunks, $file_info);
                return $this->ok($data);
            }
            return $this->ok();
        } else {
            // 上传失败获取错误信息
            return $this->fail($file->getError());
        }
    }

    /**
     * 合并文件
     */
    private function mergeChunk($tmp_dir, $chunks, $file_info)
    {
        $tmp_dir = rtrim($tmp_dir, '/') . "/";
        if (is_dir($tmp_dir)) {
            // 原始后缀
            $file_ext = pathinfo($file_info['name'], PATHINFO_EXTENSION);
            $time     = time();
            // 目录
            $save_path = './uploads/' . date('Ymd', $time) . '/';
            // 创建目录
            if (!is_dir($save_path)) {
                mkdir($save_path, 0755, true);
            }
            // 文件名
            $name = uniqid() . rand(1000, 9999) . '.' . $file_ext;
            // 保存文件
            $save_name = $save_path . $name;
            // 文件内容
            $image = '';
            // 创建保存文件
            file_put_contents($save_name, $image);
            // 合并内容
            for ($i = 1; $i <= $chunks; $i++) {
                $tmp_name = $tmp_dir . ($this->getTmpName($chunks, $i));
                if (!is_file($tmp_name)) {
                    exception($tmp_name . '文件不存在');
                }
                // 获取tmp内容
                $image = file_get_contents($tmp_name);
                // 追加写入
                file_put_contents($save_name, $image, FILE_APPEND);
                // 删除文件
                unlink($tmp_name);
            }
            // 删除临时目录
            rmdir($tmp_dir);
            // 保存文件
            $data = array(
                'type_id'     => 1,
                'md5'         => md5_file($save_name),
                'size'        => filesize($save_name),
                'title'        => $file_info['name'],
                'path'        => str_replace('\\', '/', ltrim($save_name, '.')),
                'create_time' => time(),
            );
            $data['id']   = model('File')->add($data);
            $data['path'] = request()->domain() . $data['path'];
            return $data;
        }

        return false;
    }

    /**
     * 获取分片保存临时文件名称
     * @param int $chunks
     * @param int $chunk
     */
    private function getTmpName($chunks, $chunk)
    {
        $chunksLen = strlen($chunks) + 1;
        $tmpName   = sprintf("%0" . $chunksLen . "d", $chunk) . '.tmp';
        return $tmpName;
    }
}
